home *** CD-ROM | disk | FTP | other *** search
- /* +-------------------------------------------------------------------+ */
- /* | Copyright 1992, 1993, David Koblas (koblas@netcom.com) | */
- /* | | */
- /* | Permission to use, copy, modify, and to distribute this software | */
- /* | and its documentation for any purpose is hereby granted without | */
- /* | fee, provided that the above copyright notice appear in all | */
- /* | copies and that both that copyright notice and this permission | */
- /* | notice appear in supporting documentation. There is no | */
- /* | representations about the suitability of this software for | */
- /* | any purpose. this software is provided "as is" without express | */
- /* | or implied warranty. | */
- /* | | */
- /* +-------------------------------------------------------------------+ */
-
- #include <X11/Intrinsic.h>
- #include <X11/StringDefs.h>
- #include <X11/cursorfont.h>
- #include "xpaint.h"
- #include "misc.h"
- #include "Paint.h"
-
- #define FILL 0x2
- #define POLY 0x1
- #define IsPoly(x) (x & POLY)
- #define IsFill(x) (x & FILL)
-
- #define MAXP 100
-
- typedef struct {
- int flag;
- int startX, startY, endX, endY, button;
- int drawn, first, tracking, go;
- int npoints;
- XPoint points[MAXP+1];
- XPoint real[MAXP+1];
- /*
- ** Borrowed from my info structure.
- */
- GC fgc, lgc, gcx;
- Pixmap pixmap;
- Widget widget;
- Boolean isFat;
- } LocalInfo;
-
- static void finish(Widget w, LocalInfo *l, Boolean flag)
- {
- if (!l->tracking)
- return;
-
- l->tracking = False;
-
- if (l->drawn)
- XDrawLines(XtDisplay(w), XtWindow(w), l->gcx,
- l->points, l->npoints, CoordModeOrigin);
- if (flag && l->drawn)
- XDrawLine(XtDisplay(w), XtWindow(w), l->gcx,
- l->points[l->npoints-1].x,
- l->points[l->npoints-1].y,
- l->endX, l->endY);
-
- if (IsFill(l->flag)) {
- if (!l->isFat)
- XFillPolygon(XtDisplay(w), XtWindow(w), l->fgc,
- l->real, l->npoints, Complex, CoordModeOrigin);
- XFillPolygon(XtDisplay(w), l->pixmap, l->fgc,
- l->real, l->npoints, Complex,CoordModeOrigin);
- }
-
- if (IsPoly(l->flag)) {
- l->real[l->npoints].x = l->real[0].x;
- l->real[l->npoints].y = l->real[0].y;
- l->npoints++;
- }
- if (!l->isFat)
- XDrawLines(XtDisplay(w), XtWindow(w), l->lgc,
- l->real, l->npoints, CoordModeOrigin);
- XDrawLines(XtDisplay(w), l->pixmap, l->lgc,
- l->real, l->npoints, CoordModeOrigin);
-
- PwUpdate(w, NULL, False);
- }
-
- static void press(Widget w, LocalInfo *l, XButtonEvent *event, OpInfo *info)
- {
- if (!l->tracking && event->button == Button1) {
- l->endX = l->startX = event->x;
- l->endY = l->startY = event->y;
-
- l->button = event->button;
-
- l->npoints = 0;
-
- l->points[l->npoints].x = event->x;
- l->points[l->npoints].y = event->y;
- l->real[l->npoints].x = info->x;
- l->real[l->npoints].y = info->y;
- l->npoints++;
-
- l->drawn = False;
- l->tracking = True;
- l->first = True;
-
- l->isFat = info->isFat;
- l->fgc = info->second_gc;
- l->lgc = info->first_gc;
- } else if (event->button == Button2 && l->tracking) {
- finish(w, l, True);
- return;
- }
-
- if (l->first && info->surface == opPixmap) {
- UndoStartPoint(w, info, info->x, info->y);
- l->pixmap = info->drawable;
- l->widget = w;
- }
- }
-
- static void release(Widget w, LocalInfo *l, XButtonEvent *event, OpInfo *info)
- {
- if (l->npoints == MAXP - 1)
- return;
-
- if (info->surface == opWindow) {
- if (!l->first) {
- l->endX = l->points[l->npoints].x = event->x;
- l->endY = l->points[l->npoints].y = event->y;
- l->startX = event->x;
- l->startY = event->y;
- }
- return;
- }
- if (l->first) {
- l->first = False;
- return;
- }
-
- /*
- ** else on the pixmap.
- */
- l->real[l->npoints].x = info->x;
- l->real[l->npoints].y = info->y;
- l->npoints++;
-
- UndoGrow(w, info->x, info->y);
- }
-
- static void motion(Widget w, LocalInfo *l, XMotionEvent *event, OpInfo *info)
- {
- /*
- ** Haven't done the first button press
- */
- if (!l->tracking || l->first)
- return;
-
- if (l->drawn)
- XDrawLine(XtDisplay(w), info->drawable, l->gcx,
- l->startX, l->startY, l->endX, l->endY);
-
- l->endX = event->x;
- l->endY = event->y;
-
- if (l->drawn = (l->startX != l->endX && l->startY != l->endY))
- XDrawLine(XtDisplay(w), info->drawable, l->gcx,
- l->startX, l->startY, l->endX, l->endY);
- }
-
-
- /*
- ** Those public functions
- */
- void *PolyAdd(Widget w)
- {
- LocalInfo *l = (LocalInfo*)XtMalloc(sizeof(LocalInfo));
-
- l->flag = POLY;
- l->drawn = False;
- l->first = True;
- l->tracking = False;
- l->gcx = GetGCX(w);
-
- XtVaSetValues(w, XtNcompress, True, NULL);
-
- OpAddEventHandler(w, opWindow|opPixmap, ButtonPressMask, FALSE, (OpEventProc)press, l);
- OpAddEventHandler(w, opWindow, PointerMotionMask, FALSE, (OpEventProc)motion, l);
- OpAddEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
- SetCrossHairCursor(w);
-
- return l;
- }
- void PolyRemove(Widget w, LocalInfo *l)
- {
- OpRemoveEventHandler(w, opWindow|opPixmap, ButtonPressMask, FALSE, (OpEventProc)press, l);
- OpRemoveEventHandler(w, opWindow, PointerMotionMask, FALSE, (OpEventProc)motion, l);
- OpRemoveEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
-
- finish(w, l, True);
-
- XtFree((XtPointer)l);
- }
- void *FPolyAdd(Widget w)
- {
- LocalInfo *l = (LocalInfo*)XtMalloc(sizeof(LocalInfo));
-
- l->flag = POLY|FILL;
- l->drawn = False;
- l->first = True;
- l->tracking = False;
- l->gcx = GetGCX(w);
-
- XtVaSetValues(w, XtNcompress, True, NULL);
-
- OpAddEventHandler(w, opWindow|opPixmap, ButtonPressMask, FALSE, (OpEventProc)press, l);
- OpAddEventHandler(w, opWindow, PointerMotionMask, FALSE, (OpEventProc)motion, l);
- OpAddEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
- SetCrossHairCursor(w);
-
- return l;
- }
- void FPolyRemove(Widget w, LocalInfo *l)
- {
- OpRemoveEventHandler(w, opWindow|opPixmap, ButtonPressMask, FALSE, (OpEventProc)press, l);
- OpRemoveEventHandler(w, opWindow, PointerMotionMask, FALSE, (OpEventProc)motion, l);
- OpRemoveEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
-
- finish(w, l, True);
- XtFree((XtPointer)l);
- }
- void *CLineAdd(Widget w)
- {
- LocalInfo *l = (LocalInfo*)XtMalloc(sizeof(LocalInfo));
-
- l->flag = 0;
- l->drawn = False;
- l->first = True;
- l->tracking = False;
- l->gcx = GetGCX(w);
-
- XtVaSetValues(w, XtNcompress, True, NULL);
-
- OpAddEventHandler(w, opWindow|opPixmap, ButtonPressMask, FALSE, (OpEventProc)press, l);
- OpAddEventHandler(w, opWindow, PointerMotionMask, FALSE, (OpEventProc)motion, l);
- OpAddEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
- SetCrossHairCursor(w);
-
- return l;
- }
- void CLineRemove(Widget w, LocalInfo *l)
- {
- OpRemoveEventHandler(w, opWindow|opPixmap, ButtonPressMask, FALSE, (OpEventProc)press, l);
- OpRemoveEventHandler(w, opWindow, PointerMotionMask, FALSE, (OpEventProc)motion, l);
- OpRemoveEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
-
- finish(w, l, True);
- XtFree((XtPointer)l);
- }
-